home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d953.lha / ISAM / examples / Books.c < prev    next >
C/C++ Source or Header  |  1993-11-28  |  31KB  |  1,197 lines

  1. ; /*  you can execute this file to compile it (if you're using lattice/SAS C )
  2. lc books
  3. blink from LIB:c.o books.o LIB LIB:lcm.lib LIB:lc.lib LIB:amiga.lib  
  4. quit
  5. */
  6.  
  7. #include <MYLIB:ISAMLibPROTO.h>
  8. #include <stdio.h>
  9.  
  10. struct Library *ISAMBase = NULL;
  11.  
  12. /* remove proto parm-names if your compiler can't handle them. */
  13. /* remove protos entirely, "   "      "       "     "     "    */
  14.  
  15. void FFlush ( void );
  16. void MultiScan ( char *str, int len );
  17. void FlushScan ( char *fmt, void *ptr );
  18. void FillOut ( char *str, int strlen, int len );
  19. BOOL HandlePrefix ( int keyno, void **ppprefix, int *pplen );
  20. BOOL HandleKey ( int keyno, void **ppkey );
  21. BOOL HandleRange ( int keyno, int itertype, void **ppfrom, void **ppto );
  22. void EditBook ( void );
  23. void ListCategories ( void );
  24. void ListBooks ( void );
  25. int main ( int argc, char *(argv[]) );
  26.  
  27.  
  28.   struct Book {
  29.      /* 00 */  char  Title [30];
  30.      /* 30 */  char  Author [30];
  31.      /* 60 */  char  Publisher [30];
  32.      /* 90 */  UWORD Copyright;
  33.      /* 92 */  char  Category;
  34.      /* 93 */  char  Form;  /* P-aperback, H-ardCover, T-radePB, C-offeeTable */
  35.      /* 94 */  UWORD Pages;
  36.      /* 96 */  float Value;
  37.   }; /*100 */
  38.  
  39.   struct Category {
  40.      /* 00 */  char Code;
  41.      /* 01 */  char Name [30];
  42.   }; /* 31 */
  43.  
  44.  
  45. #define MAXKEYLEN   30
  46. #define MAXKEYLENP1 (MAXKEYLEN+1)
  47.  
  48.  
  49.   extern int _OSERR;
  50.   char str80[81];
  51.   FILE *fp;
  52.   int len, i, select, keyno;
  53.   long ErrorCode;
  54.   ULONG  RecNo, tmpRecNo, CountMax, Count;
  55.  
  56.   char c, FileDev, from [MAXKEYLENP1], to [MAXKEYLENP1], key [MAXKEYLENP1];
  57.   char prefix [MAXKEYLENP1]; 
  58.   char KeyReturn [MAXKEYLENP1];  /* enough for largest key, plus 1 */
  59.   void *KeyRet = &KeyReturn[0];
  60.  
  61.   void *pfrom, *pto, *pkey, *pprefix;
  62.   int itertype;
  63.   ULONG ISAMHandleB, ISAMHandleC;
  64.   UWORD uwfrom, uwto, uwkey;
  65.   char SpecsFileNameB [] = "DATA:Book.specs";
  66.   char SpecsFileNameC [] = "DATA:BookCat.specs";
  67.   BOOL Lockk;
  68.   float ffrom, fto, fkey;
  69.   struct Book BRec;
  70.   struct Category CRec;
  71.  
  72.                              
  73. /*--------------------------------- FFlush -----------------------------------*/
  74. void FFlush ()
  75. /* if any string output is cut off because it's too long ( Ex: "%16s") */
  76. /* we don't want the overflow to count for part of the next scanf.     */
  77. {
  78.   char c;
  79.  
  80.   while ( (c = getchar () ) != '\n' )
  81.     ;
  82.  
  83.   return;
  84. }
  85.  
  86.  
  87. /*------------------------------ FlushScan ----------------------------------*/
  88. void FlushScan ( fmt, ptr )
  89.  
  90. /* this function preforms a scan, and flushes anything past the first     */
  91. /* whitespace, so we don't start assigning extra input to the next scanf. */
  92.  
  93. char *fmt;
  94. void *ptr;
  95. {
  96.   scanf ( fmt, ptr );
  97.   FFlush ();
  98. }
  99.  
  100. /*------------------------------- MultiScan ---------------------------------*/
  101. void MultiScan ( str, len )  /* for those times we want multi-word strings */
  102. char *str;
  103. int len;
  104. {
  105.   char c;
  106.  
  107.   while ( (c = getchar () ) == ' ' )
  108.     ;
  109.  
  110.   for ( i=0; ((c != '\n') && ( i < len )); i++ )
  111.   {
  112.     str [i] = c;
  113.     c = getchar ();
  114.   }
  115.   str [i] = '\0';
  116.  
  117.   if ( c != '\n' )
  118.     FFlush ();
  119.  
  120.   return;
  121. }
  122.  
  123.  
  124. /*-------------------------------- FillOut ----------------------------------*/
  125. void FillOut ( str, strlen, len )
  126. char *str;
  127. int strlen, len;
  128. {
  129.   int i;
  130.  
  131.  
  132.   if ( ( str == NULL ) || ( len == 0 ) )
  133.     return;
  134.  
  135.   for ( i=strlen; i<len; i++ )
  136.     str[i] = ' ';
  137.  
  138.   return;
  139. }
  140.  
  141.  
  142. /*------------------------------ HandlePrefix -------------------------------*/
  143. BOOL HandlePrefix ( keyno, ppprefix, plen )
  144. int keyno, *plen;
  145. void **ppprefix;
  146. {
  147.   switch ( keyno )
  148.   {
  149.     case 0 :
  150.     case 1 : 
  151.     case 2 :
  152.          printf ( "\nprefix :" );
  153.          MultiScan  ( prefix, 10 );
  154.          len = strlen ( prefix );
  155.          *ppprefix = &prefix[0];
  156.          *plen = len;
  157.          printf ( "\n'%s'", prefix );
  158.          printf ( "\n" );
  159.          break;
  160.  
  161.     case 4 :
  162.          printf ( "\nprefix :" );
  163.          FlushScan  ( "%2s", &prefix );
  164.          len = strlen ( prefix );
  165.          *ppprefix = &prefix[0];
  166.          *plen = len;
  167.          printf ( "\n'%s'", prefix );
  168.          printf ( "\n" );
  169.          ErrorCode = ReadUniqueISAMRecord ( ISAMHandleC, 0, &prefix[0],
  170.                                             FALSE, ' ', &tmpRecNo, &CRec );
  171.          switch ( ErrorCode )
  172.          {
  173.            case ERROR_NO_SUCH_RECORD :
  174.              printf ( "\nNo such Category." );
  175.              break;
  176.  
  177.            case OK :
  178.              break;
  179.  
  180.            default :
  181.              printf ( "\nError %ld.", ErrorCode );
  182.              break;
  183.          }
  184.          if ( ErrorCode != OK )
  185.            return ( FALSE );
  186.          break;
  187.  
  188.     default:
  189.          break;
  190.   }
  191.  
  192.   return ( TRUE );
  193. }
  194.  
  195.  
  196. /*------------------------------ HandleKey -------------------------------*/
  197. BOOL HandleKey ( keyno, ppkey )
  198. int keyno;
  199. void **ppkey;
  200. {
  201.   switch ( keyno )
  202.   {
  203.     case 0 :
  204.     case 1 : 
  205.     case 2 :
  206.          printf ( "\nkey :" );
  207.          MultiScan  ( key, 10 );
  208.          FillOut ( key, strlen ( key ), 10 );
  209.          *ppkey = &key[0];
  210.          printf ( "\n'%10.10s'", key );
  211.          printf ( "\n" );
  212.          break;
  213.  
  214.     case 4 :
  215.          printf ( "\nkey :" );
  216.          FlushScan  ( "%2s", &key );
  217.          FillOut ( key, strlen ( key ), 2 );
  218.          *ppkey = &key[0];
  219.          printf ( "\n'%2.2s'", key );
  220.          printf ( "\n" );
  221.          ErrorCode = ReadUniqueISAMRecord ( ISAMHandleC, 0, &key[0],
  222.                                             FALSE, ' ', &tmpRecNo, &CRec );
  223.          switch ( ErrorCode )
  224.          {
  225.            case ERROR_NO_SUCH_RECORD :
  226.              printf ( "\nNo such Category." );
  227.              break;
  228.  
  229.            case OK :
  230.              break;
  231.  
  232.            default :
  233.              printf ( "\nError %ld.", ErrorCode );
  234.              break;
  235.          }
  236.          if ( ErrorCode != OK )
  237.            return ( FALSE );
  238.          break;
  239.  
  240.     case 5 :
  241.          printf ( "\nkey :" );
  242.          FlushScan  ( "%1s", &key );
  243.          *ppkey = &key[0];
  244.          printf ( "\n'%1.1s'", key );
  245.          printf ( "\n" );
  246.          break;
  247.  
  248.     case 3 :
  249.     case 6 :
  250.          printf ( "\nkey :" );
  251.          FlushScan  ( "%hu", &uwkey );
  252.          *ppkey = &uwkey;
  253.          printf ( "\n%hu", uwkey );
  254.          printf ( "\n" );
  255.          break;
  256.  
  257.     case 7 :
  258.          printf ( "\nkey :" );
  259.          FlushScan  ( "%hf", &fkey );
  260.          *ppkey = &fkey;
  261.          printf ( "\n%8.2hf", fkey );
  262.          printf ( "\n" );
  263.          break;
  264.  
  265.     default:
  266.          break;
  267.   }
  268.  
  269.   return ( TRUE );;
  270. }
  271.  
  272.  
  273. /*----------------------------- HandleRange ------------------------------*/
  274. BOOL HandleRange ( keyno, itertype, ppfrom, ppto )
  275. int keyno, itertype;
  276. void **ppfrom, **ppto;
  277. {
  278.   *ppfrom = NULL;
  279.   *ppto   = NULL;
  280.  
  281.   switch ( keyno )
  282.   {
  283.     case 0 :
  284.     case 1 :
  285.     case 2 :
  286.          if ( (itertype == 1) || ((itertype >=4) && (itertype <=9)) )
  287.            {
  288.              printf ( "\nfrom :" );
  289.              MultiScan  ( from, 10 );
  290.              FillOut ( from, strlen ( from ), 10 );
  291.              *ppfrom = &from[0];
  292.              printf ( "\n'%10.10s'", from );
  293.              printf ( "\n" );
  294.            }
  295.  
  296.          if ( (itertype >=2) && (itertype <=7) )
  297.            {
  298.              printf ( "\nto :" );
  299.              MultiScan  ( to, 10 );
  300.              FillOut ( to, strlen ( to ), 10 );
  301.              *ppto = &to[0];
  302.              printf ( "\n'%10.10s'", to );
  303.              printf ( "\n" );
  304.            }
  305.          break;
  306.  
  307.  
  308.     case 4 : 
  309.          if ( (itertype == 1) || ((itertype >=4) && (itertype <=9)) )
  310.            {
  311.              printf ( "\nfrom :" );
  312.              FlushScan  ( "%2s", &from );
  313.              FillOut ( from, strlen ( from ), 2 );
  314.              *ppfrom = &from[0];
  315.              printf ( "\n'%2.2s'", from );
  316.              printf ( "\n" );
  317.              ErrorCode = ReadUniqueISAMRecord ( ISAMHandleC, 0, &from[0],
  318.                                             FALSE, ' ', &tmpRecNo, &CRec );
  319.              switch ( ErrorCode )
  320.              {
  321.                case ERROR_NO_SUCH_RECORD :
  322.                  printf ( "\nNo such Category." );
  323.                  break;
  324.  
  325.                case OK :
  326.                  break;
  327.  
  328.                default :
  329.                  printf ( "\nError %ld.", ErrorCode );
  330.                  break;
  331.              }
  332.              if ( ErrorCode != OK )
  333.                return ( FALSE );
  334.            }
  335.  
  336.          if ( (itertype >=2) && (itertype <=7) )
  337.            {
  338.              printf ( "\nto :" );
  339.              FlushScan  ( "%2s", &to );
  340.              FillOut ( to, strlen ( to ), 2 );
  341.              *ppto = &to[0];
  342.              printf ( "\n'%2.2s'", to );
  343.              printf ( "\n" );
  344.              ErrorCode = ReadUniqueISAMRecord ( ISAMHandleC, 0, &to[0],
  345.                                             FALSE, ' ', &tmpRecNo, &CRec );
  346.              switch ( ErrorCode )
  347.              {
  348.                case ERROR_NO_SUCH_RECORD :
  349.                  printf ( "\nNo such Category." );
  350.                  break;
  351.  
  352.                case OK :
  353.                  break;
  354.  
  355.                default :
  356.                  printf ( "\nError %ld.", ErrorCode );
  357.                  break;
  358.              }
  359.              if ( ErrorCode != OK )
  360.                return ( FALSE );
  361.            }
  362.          break;
  363.  
  364.  
  365.     case 5 : 
  366.          if ( (itertype == 1) || ((itertype >=4) && (itertype <=9)) )
  367.            {
  368.              printf ( "\nfrom :" );
  369.              FlushScan  ( "%1s", &from );
  370.              *ppfrom = &from[0];
  371.              printf ( "\n'%1.1s'", from );
  372.              printf ( "\n" );
  373.            }
  374.  
  375.          if ( (itertype >=2) && (itertype <=7) )
  376.            {
  377.              printf ( "\nto :" );
  378.              FlushScan  ( "%1s", &to );
  379.              *ppto = &to[0];
  380.              printf ( "\n'%1.1s'", to );
  381.              printf ( "\n" );
  382.            }
  383.          break;
  384.  
  385.  
  386.     case 3 :
  387.     case 6 :
  388.          if ( (itertype == 1) || ((itertype >=4) && (itertype <=9)) )
  389.            {
  390.              printf ( "\nfrom :" );
  391.              FlushScan  ( "%hu", &uwfrom );
  392.              *ppfrom = &uwfrom;
  393.              printf ( "\n%hu", uwfrom );
  394.              printf ( "\n" );
  395.            }
  396.  
  397.          if ( (itertype >=2) && (itertype <=7) )
  398.            {
  399.              printf ( "\nto :" );
  400.              FlushScan  ( "%hu", &uwto );
  401.              *ppto = &uwto;
  402.              printf ( "\n%hu", uwto );
  403.              printf ( "\n" );
  404.            }
  405.          break;
  406.  
  407.  
  408.     case 7 :
  409.          if ( (itertype == 1) || ((itertype >=4) && (itertype <=9)) )
  410.            {
  411.              printf ( "\nfrom :" );
  412.              FlushScan  ( "%hf", &ffrom );
  413.              *ppfrom = &ffrom;
  414.              printf ( "\n%8.2hf", ffrom );
  415.              printf ( "\n" );
  416.            }
  417.  
  418.          if ( (itertype >=2) && (itertype <=7) )
  419.            {
  420.              printf ( "\nto :" );
  421.              FlushScan  ( "%hf", &fto );
  422.              *ppto = &fto;
  423.              printf ( "\n%8.2hf", fto );
  424.              printf ( "\n" );
  425.            }
  426.          break;
  427.  
  428.  
  429.     default:
  430.          break;
  431.   }
  432.  
  433.   return ( TRUE );
  434. }
  435.  
  436.  
  437. /*-------------------------------- EditBook ---------------------------------*/
  438. void EditBook ()
  439. {
  440.   for (;;)
  441.   {
  442.     printf ( "\nCurrent Record:\n" );
  443.  
  444.     printf ( "\nTitle     : '%30.30s'", BRec.Title );
  445.     printf ( "\nAuthor    : '%30.30s'", BRec.Author );
  446.     printf ( "\nPublisher : '%30.30s'", BRec.Publisher );
  447.     printf ( "\nCopyright : %4u",       BRec.Copyright );
  448.     printf ( "\nCategory  : '%c'",      BRec.Category );
  449.     printf ( "\nForm      : '%c'",      BRec.Form );
  450.     printf ( "\nPages     : %6u",       BRec.Pages );
  451.     printf ( "\nValue     : %8.2lf",    BRec.Value );
  452.  
  453.     printf ( "\n\n" );
  454.     
  455.  
  456.     printf ( "\nEdit: \n" );
  457.     printf ( "\n1 : Title       5 : Category" );
  458.     printf ( "\n2 : Author      6 : Form" );
  459.     printf ( "\n3 : Publisher   7 : Pages" );
  460.     printf ( "\n4 : Copyright   8 : Value" );
  461.     printf ( "\n\n0  : end Edit\n\nSELECT ?" );
  462.  
  463.     FlushScan ( "%d", &select );
  464.     printf ( "\n" );
  465.  
  466.  
  467.     if ( select == 0 )
  468.       break;
  469.  
  470.  
  471.     switch ( select )
  472.     {
  473.       case 1 :
  474.          printf ( "\nTitle ?" );
  475.          MultiScan  ( str80, 30 );     
  476.          FillOut ( str80, strlen ( str80 ), 30 );
  477.          strncpy ( BRec.Title, str80, 30 );
  478.          break;
  479.  
  480.       case 2 :
  481.          printf ( "\nAuthor ?" );
  482.          MultiScan  ( str80, 30 );     
  483.          FillOut ( str80, strlen ( str80 ), 30 );
  484.          strncpy ( BRec.Author, str80, 30 );
  485.          break;
  486.  
  487.       case 3:
  488.          printf ( "\nPublisher ?" );
  489.          MultiScan  ( str80, 30 );     
  490.          FillOut ( str80, strlen ( str80 ), 30 );
  491.          strncpy ( BRec.Publisher, str80, 30 );
  492.          break;
  493.  
  494.       case 4 :
  495.          printf ( "\nCopyright Year ?" );
  496.          FlushScan  ( "%hu", &BRec.Copyright );
  497.          break;
  498.  
  499.       case 5 :
  500.          printf ( "\nCategory ?" );
  501.          FlushScan  ( "%1s", str80 );  
  502.          BRec.Category = toupper ( str80[0] );
  503.          ErrorCode = ReadUniqueISAMRecord ( ISAMHandleC, 0, &BRec.Category,
  504.                                             FALSE, ' ', &tmpRecNo, &CRec );
  505.          switch ( ErrorCode )
  506.          {
  507.            case ERROR_NO_SUCH_RECORD :
  508.              printf ( "\nNo such Category." );
  509.              break;
  510.  
  511.            case OK :
  512.              break;
  513.  
  514.            default :
  515.              printf ( "\nError %ld.", ErrorCode );
  516.              break;
  517.          }
  518.          break;
  519.  
  520.       case 6 :
  521.          printf ( "\nForm (P/H/T/C) ?" );
  522.          FlushScan  ( "%1s", &BRec.Form );
  523.          BRec.Form = toupper ( BRec.Form );
  524.          break;
  525.  
  526.       case 7 :
  527.          printf ( "\nNumber of Pages ?" );
  528.          FlushScan  ( "%hu", &BRec.Pages );
  529.          break;
  530.  
  531.       case 8 :
  532.          printf ( "\nValue ?" );
  533.          FlushScan  ( "%hf", &BRec.Value );
  534.          break;
  535.  
  536.       default :
  537.          printf ( "\nNo such option." );
  538.          break;
  539.     }
  540.  
  541.     continue;
  542.   }
  543.  
  544.   return;
  545. }
  546.  
  547.  
  548. /*---------------------------- ListCategories ----------------------------*/
  549. void ListCategories ()
  550. {
  551.   ErrorCode = SetUpISAMIterationRange ( ISAMHandleC, 0, 0, NULL, NULL );
  552.   if ( ErrorCode != OK )
  553.     {
  554.       printf ( "\nCouldn't set up list." );
  555.       printf ( "\nError %ld.", ErrorCode );
  556.       return;
  557.     }
  558.   if (( ErrorCode = CountISAMRecords ( ISAMHandleC, 0, 0L, &Count )) != OK )
  559.     {
  560.       printf ( "\nCouldn't count Categories." );
  561.       printf ( "\nError %ld.", ErrorCode );
  562.       return;
  563.     }
  564.   switch ( Count )
  565.   {
  566.     case 0L : printf ( "\nThere are no Categories." );         break;
  567.     case 1L : printf ( "\nThere is 1 Category." );             break;
  568.     default : printf ( "\nThere are %lu Categories.", Count ); break;
  569.   }
  570.   if ( Count == 0L )
  571.     return;
  572.  
  573.   for (;;)
  574.   {
  575.     printf ( "\n\nPrint the List to someplace other than the screen? (Y/N) " );
  576.     FlushScan  ( "%1s", &FileDev );
  577.     FileDev = toupper ( FileDev );
  578.     if ( ( FileDev == 'Y' ) || ( FileDev == 'N' ) )
  579.       break;
  580.     printf ( "\nNot an option." );
  581.   }
  582.  
  583.   if ( FileDev == 'Y' )
  584.     {
  585.       printf ( "\nFile/Device Name: " );
  586.       FlushScan  ( "%80s", str80 );
  587.       if ( ( fp = fopen ( str80, "w" )) == NULL )
  588.         {
  589.           printf ( "\nCouldn't open '%s' for output.", str80 );
  590.           printf ( "\nError: %d", _OSERR );
  591.           return;
  592.         }
  593.     }
  594.    else
  595.     {
  596.       fp = stdout;
  597.     }
  598.  
  599.   fprintf ( fp, "\n\nCODE ---------- Category ----------\n" );
  600.  
  601.   fprintf ( fp,   "\n===================================\n" );
  602.  
  603.   do
  604.     {
  605.       ErrorCode = ReadNextISAMRecord ( ISAMHandleC, 0,
  606.                           FALSE, ' ', &RecNo, &CRec );
  607.       switch ( ErrorCode )
  608.       {
  609.         case OK :
  610.           fprintf ( fp, "\n  %c    %30.30s", CRec.Code, CRec.Name );
  611.           break;
  612.  
  613.         case ERROR_NO_MORE_RECORDS :
  614.           break;
  615.  
  616.         default :
  617.           fprintf ( fp, "\nError %ld.", ErrorCode );
  618.           break;
  619.       }
  620.     }
  621.   while ( ErrorCode == OK );
  622.  
  623.   if ( FileDev == 'Y' )
  624.     {
  625.       fclose ( fp );
  626.     }
  627.  
  628.   return;  
  629. }
  630.  
  631.  
  632. /*------------------------------- ListBooks ------------------------------*/
  633. void ListBooks ()
  634. {
  635.   for (;;)
  636.   {
  637.     printf ( "\nList Books by what key: \n" );
  638.     printf ( "\n1 : Title       5 : Category/Form" );
  639.     printf ( "\n2 : Author      6 : Form" );
  640.     printf ( "\n3 : Publisher   7 : Pages" );
  641.     printf ( "\n4 : Copyright   8 : Value" );
  642.     printf ( "\n\nSELECT ?" );
  643.  
  644.     FlushScan ( "%d", &select );
  645.     printf ( "\n" );
  646.     if ( ( select < 1 ) || ( select > 8 ) )
  647.       {
  648.         printf ( "\nNo such option." );
  649.         continue;
  650.       }
  651.     keyno = select - 1;
  652.     break;
  653.   }
  654.  
  655.   for (;;)
  656.   {
  657.     printf ( "\nList by:\n" );
  658.     printf ( "\n1 : All key values." );
  659.     printf ( "\n2 : Range of key values." );
  660.     printf ( "\n3 : One key value." );
  661.     printf ( "\n4 : Key prefix (keys 1/2/3/5 only). " );
  662.     printf ( "\n\nSELECT ?" );
  663.  
  664.     FlushScan ( "%d", &select );
  665.     printf ( "\n" );
  666.     if ( ( select < 1 ) || ( select > 4 ) )
  667.       {
  668.         printf ( "\nNo such option." );
  669.         continue;
  670.       }
  671.     if ( select==4 )
  672.       switch ( keyno+1 )
  673.       {
  674.         case 1 : case 2 : case 3 : case 5 :
  675.           break;
  676.  
  677.         default:
  678.           printf ( "\nNot valid for key selected." );
  679.           continue;
  680.       }
  681.     break;
  682.   }
  683.  
  684.   switch ( select )
  685.   {
  686.     case 1 : 
  687.     case 2 : itertype = ( select == 1 ) ? 0 : 7;
  688.              if ( !HandleRange ( keyno, itertype, &pfrom, &pto ))
  689.                return;
  690.              ErrorCode = SetUpISAMIterationRange ( ISAMHandleB,
  691.                                 (UWORD) keyno, (UBYTE) itertype, pfrom, pto );
  692.              break;
  693.              
  694.     case 3 : if ( !HandleKey ( keyno, &pkey) )
  695.                return;
  696.              ErrorCode = SetUpISAMIterationKey ( ISAMHandleB, (UWORD) keyno,
  697.                                                    pkey );
  698.              break;
  699.  
  700.     case 4 : if ( !HandlePrefix ( keyno, &pprefix, &len) )
  701.                return;
  702.              ErrorCode = SetUpISAMIterationPrefix ( ISAMHandleB, (UWORD) keyno,
  703.                                          pprefix, len );
  704.              break;
  705.  
  706.     default: break;
  707.   }
  708.   if ( ErrorCode != OK )
  709.     {
  710.       printf ( "\nCouldn't set up list." );
  711.       printf ( "\nError %ld.", ErrorCode );
  712.       return;
  713.     }
  714.  
  715.   printf ( "\nStop Counting at how many Books: " );
  716.   FlushScan  ( "%lu", &CountMax );
  717.   printf ( "\n" );
  718.  
  719.   if (( ErrorCode = CountISAMRecords ( ISAMHandleB, (UWORD) keyno,
  720.                                        CountMax, &Count )) != OK )
  721.     {
  722.       printf ( "\nCouldn't count Books." );
  723.       printf ( "\nError %ld.", ErrorCode );
  724.       return;
  725.     }
  726.   switch ( Count )
  727.   {
  728.     case 0L : printf ( "\nThere are no Books" );         break;
  729.     case 1L : printf ( "\nThere is 1 Book" );            break;
  730.     default : printf ( "\nThere are %lu Books", Count ); break;
  731.   }
  732.   printf ( " matching that criteria." );
  733.   if ( Count == 0L )
  734.     return;
  735.  
  736.   for (;;)
  737.   {
  738.     printf ( "\n\nPrint the List to someplace other than the screen? (Y/N) " );
  739.     FlushScan  ( "%1s", &FileDev );
  740.     FileDev = toupper ( FileDev );
  741.     if ( ( FileDev == 'Y' ) || ( FileDev == 'N' ) )
  742.       break;
  743.     printf ( "\nNot an option." );
  744.   }
  745.  
  746.   if ( FileDev == 'Y' )
  747.     {
  748.       printf ( "\nFile/Device Name: " );
  749.       FlushScan  ( "%80s", str80 );
  750.       if ( ( fp = fopen ( str80, "w" )) == NULL )
  751.         {
  752.           printf ( "\nCouldn't open '%s' for output.", str80 );
  753.           printf ( "\nError: %d", _OSERR );
  754.           return;
  755.         }
  756.     }
  757.    else
  758.     {
  759.       fp = stdout;
  760.     }
  761.   fprintf ( fp, "\n" );
  762.   fprintf ( fp,
  763. "\nRECNO ----------- TITLE ------------ ----------- AUTHOR -----------" );
  764.   fprintf ( fp,
  765. "\n      --------- PUBLISHER ---------- COPY. CAT. FORM -$VALUE- #PAGES\n" );
  766.   fprintf ( fp,
  767. "\n====================================================================\n" );
  768.  
  769.   do
  770.     {
  771.       ErrorCode = ReadNextISAMRecord ( ISAMHandleB, (UWORD) keyno,
  772.                           FALSE, ' ', &RecNo, &BRec );
  773.       switch ( ErrorCode )
  774.       {
  775.         case OK :
  776.           fprintf ( fp, "\n%5lu %30.30s %30.30s\n      ", RecNo,
  777.                     BRec.Title, BRec.Author );
  778.           fprintf ( fp, "%30.30s %4hu   %c     %c  %8.2f %6hu\n",
  779.                     BRec.Publisher, BRec.Copyright, BRec.Category, BRec.Form,
  780.                     BRec.Value, BRec.Pages );
  781.           break;
  782.  
  783.         case ERROR_NO_MORE_RECORDS :
  784.           break;
  785.  
  786.         default :
  787.           fprintf ( fp, "\nError %ld.", ErrorCode );
  788.           break;
  789.       }
  790.     }
  791.   while ( ErrorCode == OK );
  792.  
  793.   if ( FileDev == 'Y' )
  794.     {
  795.       fclose ( fp );
  796.     }
  797.  
  798.   return;  
  799. }
  800.  
  801.  
  802. /*================================= MAIN =================================*/
  803.  
  804. main ( argc, argv )
  805. int argc;
  806. char *(argv[]);
  807. {
  808.   if ( (ISAMBase = OpenLibrary ( "isam.library", 0 )) == NULL )
  809.     {
  810.       printf ( "\nCouldn't open ISAM library.\n\n" );
  811.       exit ( 5 );
  812.     }
  813.  
  814.   if (( ErrorCode = OpenISAMFile ( SpecsFileNameB, TRUE, 'R', 
  815.                                    TRUE, &ISAMHandleB )) != OK )
  816.     {
  817.       printf ( "\nError %ld.", ErrorCode );
  818.       goto END;
  819.     }
  820.   if (( ErrorCode = OpenISAMFile ( SpecsFileNameC, TRUE, 'R', 
  821.                                    TRUE, &ISAMHandleC )) != OK )
  822.     {
  823.       printf ( "\nError %ld.", ErrorCode );
  824.       goto END;
  825.     }
  826.  
  827.   for (;;)
  828.   {
  829.     printf ( "\n" );
  830.     printf ( "\n1  : Store  Book     5 : Store  Book Category" );
  831.     printf ( "\n2  : Modify Book     6 : Modify Book Category" );
  832.     printf ( "\n3  : Delete Book     7 : Delete Book Category" );
  833.     printf ( "\n4  : List   Books    8 : List   Book Categories" );
  834.     printf ( "\n\n0  : exit\n\nSELECT ?" );
  835.  
  836.     FlushScan ( "%d", &select );
  837.     printf ( "\n" );
  838.  
  839.  
  840.     if ( select == 0 )
  841.       break;
  842.  
  843.  
  844.  
  845.     switch ( select )
  846.     {
  847.       case 1 :
  848.          printf ( "\nCategory ?" );
  849.          FlushScan  ( "%1s", str80 );  
  850.          BRec.Category = toupper ( str80[0] );
  851.          ErrorCode = ReadUniqueISAMRecord ( ISAMHandleC, 0, &BRec.Category,
  852.                                             FALSE, ' ', &tmpRecNo, &CRec );
  853.          switch ( ErrorCode )
  854.          {
  855.            case ERROR_NO_SUCH_RECORD :
  856.              printf ( "\nNo such Category." );
  857.              break;
  858.  
  859.            case OK :
  860.              break;
  861.  
  862.            default :
  863.              printf ( "\nError %ld.", ErrorCode );
  864.              break;
  865.          }
  866.          if ( ErrorCode != OK )
  867.            break;
  868.  
  869.          printf ( "\nTitle ?" );
  870.          MultiScan  ( str80, 30 );     
  871.          FillOut ( str80, strlen ( str80 ), 30 );
  872.          strncpy ( BRec.Title, str80, 30 );
  873.  
  874.          printf ( "\nAuthor ?" );
  875.          MultiScan  ( str80, 30 );     
  876.          FillOut ( str80, strlen ( str80 ), 30 );
  877.          strncpy ( BRec.Author, str80, 30 );
  878.  
  879.          printf ( "\nPublisher ?" );
  880.          MultiScan  ( str80, 30 );     
  881.          FillOut ( str80, strlen ( str80 ), 30 );
  882.          strncpy ( BRec.Publisher, str80, 30 );
  883.  
  884.          printf ( "\nCopyright Year ?" );
  885.          FlushScan  ( "%hu", &BRec.Copyright );
  886.  
  887.          printf ( "\nForm (P/H/T/C) ?" );
  888.          FlushScan  ( "%1s", &BRec.Form );  
  889.          BRec.Form = toupper ( BRec.Form );
  890.  
  891.          printf ( "\nNumber of Pages ?" );
  892.          FlushScan  ( "%hu", &BRec.Pages );
  893.  
  894.          printf ( "\nValue ?" );
  895.          FlushScan  ( "%hf", &BRec.Value );
  896.  
  897.  
  898.          printf ( "\nEnter a number to Store Book: ('-1' to abort) ");
  899.          FlushScan  ( "%d", &i );
  900.          printf ( "\n" );
  901.          if ( i == -1 )
  902.            break;
  903.        
  904.          ErrorCode = StoreISAMRecord ( ISAMHandleB, &BRec, FALSE, ' ', &RecNo );
  905.          switch ( ErrorCode )
  906.          {
  907.            case OK :
  908.              printf ( "\nRecord# %lu", RecNo );
  909.              break;
  910.  
  911.            default :
  912.              printf ( "\nError %ld.", ErrorCode );
  913.              break;
  914.          }
  915.          break;
  916.  
  917.  
  918.       case 2 :
  919.          printf ( "\nRec# :" );
  920.          FlushScan  ( "%lu", &RecNo );
  921.          printf ( "\n" );
  922.  
  923.          ErrorCode = ReadISAMRecord ( ISAMHandleB, RecNo, FALSE, ' ', &BRec );
  924.          switch ( ErrorCode )
  925.          {
  926.            case ERROR_DELETED_RECORD :
  927.              printf ( "\nThat record has been deleted." );
  928.              break;
  929.  
  930.            case ERROR_RECORD_TOO_HIGH :
  931.              printf ( "\nThat record number is too high." );
  932.              break;
  933.  
  934.            case OK :
  935.              break;
  936.  
  937.            default:
  938.              printf ( "\nError %ld.", ErrorCode );
  939.      }
  940.          if ( ErrorCode != OK )
  941.            break;
  942.  
  943.          EditBook ();
  944.            
  945.  
  946.          printf ( "\nEnter a number to Modify Book: ('-1' to abort) ");
  947.          FlushScan  ( "%d", &i );
  948.          printf ( "\n" );
  949.          if ( i == -1 )
  950.            break;
  951.        
  952.          ErrorCode = ModifyISAMRecord ( ISAMHandleB, RecNo, &BRec );
  953.          switch ( ErrorCode )
  954.          {
  955.            case OK :
  956.              printf ( "\nBook Modified." );
  957.              break;
  958.  
  959.            default :
  960.              printf ( "\nError %ld.", ErrorCode );
  961.              break;
  962.          }
  963.          break;
  964.  
  965.  
  966.       case 3 :
  967.          printf ( "\nRec# :" );
  968.          FlushScan  ( "%lu", &RecNo );
  969.          printf ( "\n" );
  970.  
  971.          ErrorCode = ReadISAMRecord ( ISAMHandleB, RecNo, FALSE, ' ', &BRec );
  972.          switch ( ErrorCode )
  973.          {
  974.            case ERROR_DELETED_RECORD :
  975.              printf ( "\nThat record has been deleted." );
  976.              break;
  977.  
  978.            case ERROR_RECORD_TOO_HIGH :
  979.              printf ( "\nThat record number is too high." );
  980.              break;
  981.  
  982.            case OK :
  983.              printf ( "\nTitle     : '%30.30s'", BRec.Title );
  984.              printf ( "\nAuthor    : '%30.30s'", BRec.Author );
  985.              printf ( "\nPublisher : '%30.30s'", BRec.Publisher );
  986.              printf ( "\nCopyright : %4u",       BRec.Copyright );
  987.              printf ( "\nCategory  : '%c'",      BRec.Category );
  988.              printf ( "\nForm      : '%c'",      BRec.Form );
  989.              printf ( "\nPages     : %6u",       BRec.Pages );
  990.              printf ( "\nValue     : %8.2lf",    BRec.Value );
  991.              printf ( "\n" );
  992.              break;
  993.  
  994.            default:
  995.              printf ( "\nError %ld.", ErrorCode );
  996.      }
  997.          if ( ErrorCode != OK )
  998.            break;
  999.  
  1000.          printf ( "\nEnter a number to Delete Book: ('-1' to abort) ");
  1001.          FlushScan  ( "%d", &i );
  1002.          printf ( "\n" );
  1003.          if ( i == -1 )
  1004.            break;
  1005.        
  1006.          ErrorCode = DeleteISAMRecord ( ISAMHandleB, RecNo );
  1007.          switch ( ErrorCode )
  1008.          {
  1009.            case ERROR_DELETED_RECORD :
  1010.              printf ( "\nThat record has been deleted." );
  1011.              break;
  1012.  
  1013.            case ERROR_RECORD_TOO_HIGH :
  1014.              printf ( "\nThat record number is too high." );
  1015.              break;
  1016.  
  1017.            case OK :
  1018.              printf ( "\nRecord deleted." );
  1019.              break;
  1020.  
  1021.            default:
  1022.              printf ( "\nError %ld.", ErrorCode );
  1023.      }
  1024.          break;
  1025.  
  1026.  
  1027.       case 4 :
  1028.          ListBooks ();
  1029.          break;
  1030.  
  1031.  
  1032.       case 5 :
  1033.          printf ( "\nCategory Code ?" );
  1034.          FlushScan  ( "%1s", &CRec.Code );  
  1035.          CRec.Code = toupper ( CRec.Code );
  1036.  
  1037.          printf ( "\nCategory Name ?" );
  1038.          MultiScan  ( str80, 30 );     
  1039.          FillOut ( str80, strlen ( str80 ), 30 );
  1040.          strncpy ( CRec.Name, str80, 30 );
  1041.  
  1042.  
  1043.          printf ( "\nEnter a number to Store Category: ('-1' to abort) ");
  1044.          FlushScan  ( "%d", &i );
  1045.          printf ( "\n" );
  1046.          if ( i == -1 )
  1047.            break;
  1048.        
  1049.          ErrorCode = StoreISAMRecord ( ISAMHandleC, &CRec, FALSE, ' ', &RecNo );
  1050.          switch ( ErrorCode )
  1051.          {
  1052.            case ERROR_RECORD_EXISTS :
  1053.              printf ( "\nThat Category already exists." );
  1054.              break;
  1055.  
  1056.            case OK :
  1057.              printf ( "\nRecord# %lu", RecNo );
  1058.              break;
  1059.  
  1060.            default :
  1061.              printf ( "\nError %ld.", ErrorCode );
  1062.              break;
  1063.          }
  1064.          break;
  1065.  
  1066.  
  1067.       case 6 :
  1068.          printf ( "\nCategory Code ?" );
  1069.          FlushScan  ( "%1s", &CRec.Code );  
  1070.  
  1071.          ErrorCode = ReadUniqueISAMRecord ( ISAMHandleC, 0, &CRec.Code,
  1072.                                             FALSE, ' ', &RecNo, &CRec );
  1073.          switch ( ErrorCode )
  1074.          {
  1075.            case ERROR_NO_SUCH_RECORD :
  1076.              printf ( "\nNo such Category." );
  1077.              break;
  1078.  
  1079.            case OK :
  1080.              break;
  1081.  
  1082.            default :
  1083.              printf ( "\nError %ld.", ErrorCode );
  1084.              break;
  1085.          }
  1086.          if ( ErrorCode != OK )
  1087.            break;
  1088.          printf ( "\n'%30.30s'\n", CRec.Name );
  1089.          
  1090.          printf ( "\nNew Category Code ?" );
  1091.          FlushScan  ( "%1s", str80 );  
  1092.          CRec.Code = toupper ( str80[0] );
  1093.  
  1094.          printf ( "\nNew Category Name ?" );
  1095.          printf ( "\n(currently: '%30.30s')\n", CRec.Name );
  1096.          MultiScan  ( str80, 30 );     
  1097.          FillOut ( str80, strlen ( str80 ), 30 );
  1098.          strncpy ( CRec.Name, str80, 30 );
  1099.  
  1100.          printf ( "\nEnter a number to Modify Category: ('-1' to abort) ");
  1101.          FlushScan  ( "%d", &i );
  1102.          printf ( "\n" );
  1103.          if ( i == -1 )
  1104.            break;
  1105.        
  1106.          ErrorCode = ModifyISAMRecord ( ISAMHandleC, RecNo, &CRec );
  1107.          switch ( ErrorCode )
  1108.          {
  1109.            case ERROR_RECORD_EXISTS :
  1110.              printf ( "\nThat Category already exists." );
  1111.              break;
  1112.  
  1113.            case OK :
  1114.              printf ( "\nCategory Modified." );
  1115.              break;
  1116.  
  1117.            default :
  1118.              printf ( "\nError %ld.", ErrorCode );
  1119.              break;
  1120.          }
  1121.          break;
  1122.  
  1123.  
  1124.       case 7 :
  1125.          printf ( "\nCategory Code ?" );
  1126.          FlushScan  ( "%1s", &CRec.Code );  
  1127.  
  1128.          ErrorCode = ReadUniqueISAMRecord ( ISAMHandleC, 0, &CRec.Code,
  1129.                                             FALSE, ' ', &RecNo, &CRec );
  1130.          switch ( ErrorCode )
  1131.          {
  1132.            case ERROR_NO_SUCH_RECORD :
  1133.              printf ( "\nNo such Category." );
  1134.              break;
  1135.  
  1136.            case OK :
  1137.              break;
  1138.  
  1139.            default :
  1140.              printf ( "\nError %ld.", ErrorCode );
  1141.              break;
  1142.          }
  1143.          if ( ErrorCode != OK )
  1144.            break;
  1145.  
  1146.          printf ( "\nCategory Code: '%c'",      CRec.Code );
  1147.          printf ( "\n         Name: '%30.30s'", CRec.Name );
  1148.          printf ( "\n" );
  1149.  
  1150.          printf ( "\nEnter a number to Delete Category: ('-1' to abort) ");
  1151.          FlushScan  ( "%d", &i );
  1152.          printf ( "\n" );
  1153.          if ( i == -1 )
  1154.            break;
  1155.        
  1156.          ErrorCode = DeleteISAMRecord ( ISAMHandleC, RecNo );
  1157.          switch ( ErrorCode )
  1158.          {
  1159.            case OK :
  1160.              printf ( "\nCategory deleted." );
  1161.              break;
  1162.  
  1163.            default:
  1164.              printf ( "\nError %ld.", ErrorCode );
  1165.      }
  1166.          break;
  1167.  
  1168.  
  1169.       case 8 :
  1170.          ListCategories ();
  1171.          break;
  1172.  
  1173.  
  1174.       default :
  1175.          printf ( "\nNo such option." );
  1176.          break;
  1177.     }
  1178.  
  1179.     continue;
  1180.   }  /* for */
  1181.  
  1182.  
  1183. END:
  1184.  
  1185.   if ( ISAMHandleB && (( ErrorCode = CloseISAMFile ( ISAMHandleB )) != OK ))
  1186.     printf ( "\nError %ld.", ErrorCode );
  1187.  
  1188.   if ( ISAMHandleC && (( ErrorCode = CloseISAMFile ( ISAMHandleC )) != OK ))
  1189.     printf ( "\nError %ld.", ErrorCode );
  1190.  
  1191.   CloseLibrary ( ISAMBase );
  1192.  
  1193.   printf ( "\n\n" );
  1194.  
  1195.   return;
  1196. }
  1197.